package com.d4a5.mapping.google2
{
	import com.google.maps.overlays.MarkerOptions;
	import com.google.maps.overlays.PolygonOptions;
	import com.google.maps.overlays.PolylineOptions;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;

	public class wmgOverlayLayerRenderer implements IEventDispatcher
	{
		
		public var innerRenderer:wmgOverlayLayerRenderer;
		public var defaultOptions:Object;
		
		protected var _selectedOptions:Object;
		protected var _highlightedOptions:Object;
		protected var _bothOptions:Object;
		protected var _eventDispatcher:EventDispatcher;
		protected var _needsUpdating:Object;
		
		
		public function wmgOverlayLayerRenderer()
		{
			this._eventDispatcher = new EventDispatcher( this );
		}
		
		public function getOptions( overlay:wmgOverlayLayerBaseShape , overlayDefaultOptions:Object = null ): Object {
			var options:Object = (overlayDefaultOptions) ? overlayDefaultOptions : this.defaultOptions;
		
			if( this.innerRenderer ){
				options = this.innerRenderer.getOptions( overlay , overlayDefaultOptions );
			}
			
			if( options == null ){
				if( overlay is wmgOverlayLayerMarker ){
					options = MarkerOptions.getDefaultOptions();
				}
				else if( overlay is wmgOverlayLayerPolyline ){
					options = PolylineOptions.getDefaultOptions();
				}
				else if( overlay is wmgOverlayLayerPolygon ){
					options = PolygonOptions.getDefaultOptions();
				}
			}
			
			if( overlay.selected ){
				if( overlay.highlighted && this.bothOptions ){
					options = this.getNewOptions( options , this.bothOptions );
				}
				else if( this.selectedOptions ){
					options = this.getNewOptions( options , this.selectedOptions );
				}
			}
			else if( overlay.highlighted && this.highlightedOptions ){
				options = this.getNewOptions( options , this.highlightedOptions );
			}
			
			return options;
		}
		
		
		protected function getNewOptions( options:Object , stateOptions:Object ) : Object {
			var newOptions:Object = options;
			
			//var color:uint = this.calculateColorWithAlpha( (stateOptions as Object).color,  (symbol as Object).color , (stateSymbol as Object).alpha );
			
			if( options is MarkerOptions && stateOptions is MarkerOptions ){
				newOptions = MarkerOptions.merge( [options,stateOptions] );
			}
			else if( options is PolylineOptions && stateOptions is PolylineOptions ){
				newOptions = PolylineOptions.merge( [options,stateOptions] );
			}
			else if( options is PolygonOptions && stateOptions is PolygonOptions ){
				newOptions = PolygonOptions.merge( [options,stateOptions] );
			}
			
			return newOptions;
		}
		
		
		protected function calculateColorWithAlpha( top:uint , bottom:uint , alpha:Number ) : uint {
			if( alpha == 1 ){
				return top;
			}
			else if( alpha == 0 ){
				return bottom;
			}
			
			var red:uint = ((((top >> 16) & 0xff) - ((bottom >> 16) & 0xff)) * alpha) + ((bottom >> 16) & 0xff);
			var green:uint = ((((top >> 8) & 0xff) - ((bottom >> 8) & 0xff)) * alpha) + ((bottom >> 8) & 0xff);
			var blue:uint = (((top & 0xff) - (bottom & 0xff)) * alpha) + (bottom & 0xff);
			
			return (((red & 0xff) << 16) | ((green & 0xff) << 8) | (blue & 0xff));
		}
		
		
		public function get highlightedOptions() : Object{
			return this._highlightedOptions;	
		}
		public function set highlightedOptions( options:Object ) : void {
			if( options != this._highlightedOptions ){
				this._highlightedOptions = options;
				this._needsUpdating = [{overlayMethod:"highlightable",overlayValue:(options !=null)}];
				this.dispatchEvent( new Event( "renderer_changed" ) );
			}
		}
		
		public function get selectedOptions() : Object{
			return this._selectedOptions;	
		}
		public function set selectedOptions( options:Object ) : void {
			if( options != this._selectedOptions ){
				this._selectedOptions = options;
				this._needsUpdating = [{overlayMethod:"selectable",overlayValue:(options !=null)}];
				this.dispatchEvent( new Event( "renderer_changed" ) );
			}
		}
		
		public function get bothOptions() : Object{
			return this._bothOptions;	
		}
		public function set bothOptions( options:Object ) : void {
			if( options != this._bothOptions ){
				this._bothOptions = options;
				this._needsUpdating = [{overlayMethod:"selectable",overlayValue:(options !=null)},{overlayMethod:"highlightable",overlayValue:(options !=null)}];
				this.dispatchEvent( new Event( "renderer_changed" ) );
			}
		}
		
		public function get needsUpdating() : Boolean {
			return (this._needsUpdating != null);
		}
		public function update( overlay:wmgOverlayLayerBaseShape ) : void {
			if( this._needsUpdating is Array ){
				var numUpdates:int = this._needsUpdating.length;
				for( var i:int = 0; i < numUpdates; i++ ){
					overlay[ this._needsUpdating[i].overlayMethod ] =  this._needsUpdating[i].overlayValue;
				}
			}
		}
		
		public function startUpdating() : void {
			
		}
		public function endUpdating() : void {
			this._needsUpdating = null;
		}
		
		
		public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			this._eventDispatcher.addEventListener( type , listener , useCapture , priority , useWeakReference );
		}
		
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
		{
			this._eventDispatcher.removeEventListener( type , listener , useCapture );
		}
		
		public function dispatchEvent(event:Event):Boolean
		{
			return this._eventDispatcher.dispatchEvent( event );
		}
		
		public function hasEventListener(type:String):Boolean
		{
			return this._eventDispatcher.hasEventListener( type );
		}
		
		public function willTrigger(type:String):Boolean
		{
			return this._eventDispatcher.willTrigger( type );
		}
	}
}